import serverConfig from "./config";
import {
  getCookie,
  setCookie
} from "./index";
import axios from 'axios';
const normalAxios = axios.create();
const tokenUrl = serverConfig.primary + '/api/token';

export const reqToken = () => {
  return new Promise(function (resolve, reject) {
    // 从cookie取出token信息
    let token = getCookie('token');
    if (token) {
      resolve(token);
      return;
    }
    let storage = window.localStorage;
    let loginId = storage.getItem('ln');
    let password = storage.getItem('p');
    normalAxios({
      method: "post",
      url: tokenUrl,
      data: {
        loginId: loginId,
        password: password
      },
      headers: {
        'Content-Type': 'application/json'
      }
    }).then((res) => {
      if (res.data.code == 0) {
        setCookie('token', res.data.data.token, 1000 * 60 * 50);
        resolve(res.data.data.token);
        return;
      }
      reject(res.data);
    }).catch((err) => {
      reject(err);
    });
  });
}

const getURI = (url, token) => {
  if (!url) {
    return url;
  }
  let sign = "";
  let tokenString = "";
  if (token && token.trim().length > 0) {
    sign = "?";
    tokenString = "token=" + token;
  }
  if (url.indexOf("?") > -1) {
    sign = "&";
  }
  return url + sign + tokenString;
}

const mergeConfig = (target, source) => {
  if (source) {
    delete source.url
    delete source.data
    delete source.params
  }
  Object.assign(target, source || {});
}

export const requestTokenProxy = (config) => {
  return new Promise(function (resolve, reject) {
    reqToken().then(token => {
      config.url = getURI(config.url, token);
      normalAxios(config).then((res) => {
        resolve(res.data);
      }).catch((err) => {
        reject(err);
      });
    });
  });
}

export const mockAxiosDecorator = (mockAxios) => {
  return {
    get: (url, params, config) => {
      let conf = {
        method: "get",
        url,
        params
      }
      mergeConfig(conf, config);
      return new Promise(function (resolve, reject) {
        mockAxios(conf).then((res) => {
          resolve(res.data);
        }).catch((err) => {
          reject(err);
        });
      });
    },
    post: (url, params, config) => {
      let conf = {
        method: "post",
        url,
        params,
        headers: {
          'Content-Type': 'application/json'
        }
      }
      mergeConfig(conf, config);
      return new Promise(function (resolve, reject) {
        mockAxios(conf).then((res) => {
          resolve(res.data);
        }).catch((err) => {
          reject(err);
        });
      });
    },
    delete: (url, params, config, server = "primary") => {
      let conf = {
        method: "delete",
        url,
        params
      }
      mergeConfig(conf, config);
      Object.assign(conf, config || {});
      return new Promise(function (resolve, reject) {
        mockAxios(conf).then((res) => {
          resolve(res.data);
        }).catch((err) => {
          reject(err);
        });
      });
    },
    put: (url, params, config, server = "primary") => {
      let conf = {
        method: "put",
        url,
        params,
        headers: {
          'Content-Type': 'application/json'
        }
      }
      mergeConfig(conf, config);
      return new Promise(function (resolve, reject) {
        mockAxios(conf).then((res) => {
          resolve(res.data);
        }).catch((err) => {
          reject(err);
        });
      });
    }
  }
}

export const tokenProxy = {
  get: (url, data, config, server = "primary") => {
    let conf = {
      method: "get",
      url: serverConfig[server] + url,
      params: data
    }
    mergeConfig(conf, config);
    return requestTokenProxy(conf, config);
  },
  post: (url, data, config, server = "primary") => {
    let conf = {
      method: "post",
      url: serverConfig[server] + url,
      data,
      headers: {
        'Content-Type': 'application/json'
      }
    }
    mergeConfig(conf, config);
    return requestTokenProxy(conf);
  },
  delete: (url, data, config, server = "primary") => {
    let conf = {
      method: "delete",
      url: serverConfig[server] + url,
      params: data
    }
    mergeConfig(conf, config);
    Object.assign(conf, config || {});
    return requestTokenProxy(conf);
  },
  put: (url, data, config, server = "primary") => {
    let conf = {
      method: "put",
      url: serverConfig[server] + url,
      data,
      headers: {
        'Content-Type': 'application/json'
      }
    }
    mergeConfig(conf, config);
    return requestTokenProxy(conf);
  },
}

export const axiosTokenProxy = {
  get: (url, config, server = "primary") => {
    let conf = {
      method: "get",
      url: serverConfig[server] + url,
      params: config.params
    }
    mergeConfig(conf, config);
    return requestTokenProxy(conf);
  },
  post: (url, config, server = "primary") => {
    let conf = {
      method: "post",
      url: serverConfig[server] + url,
      data: config.params,
      headers: {
        'Content-Type': 'application/json'
      }
    }
    mergeConfig(conf, config);
    return requestTokenProxy(conf);
  },
  delete: (url, config, server = "primary") => {
    let conf = {
      method: "delete",
      params: config.params,
      url: serverConfig[server] + url
    }
    mergeConfig(conf, config);
    return requestTokenProxy(conf);
  },
  put: (url, config, server = "primary") => {
    let conf = {
      method: "put",
      data: config.params,
      url: serverConfig[server] + url,
      headers: {
        'Content-Type': 'application/json'
      }
    }
    mergeConfig(conf, config);
    return requestTokenProxy(conf);
  },
}

export default tokenProxy;
